package net.rvb1.gwt.grad.ui.client.selection;

import com.bfr.client.selection.Range;
import com.bfr.client.selection.Selection;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Node;
import com.google.gwt.view.client.CellPreviewEvent;

/**
 * GRad helper for the {@link Selection gwt-selection} library.
 * 
 * @see <a href="http://code.google.com/p/gwt-selection/">gwt-selection library website</a>
 */
public final class SelectionHelper {

  /**
   * Indique si le {@link Node} cible de l'évènement <code>event</code> a une intersection DOM avec
   * l'ancêtre commun de la sélection courante.
   * 
   * @param event L'évènement à analyser
   * 
   * @return <code>true</code> si la cible a une intersection avec la sélection, <code>false</code>
   *         sinon.
   * 
   * @see Range#getCommonAncestor()
   */
  public static boolean isEventTargetRelatedToSelection(final CellPreviewEvent<?> event) {
    final Selection selection = Selection.getSelection();
    if (selection.isEmpty()) {
      return false;
    }

    Element rangeSelectionCommonAncestor = null;
    boolean eventTargetIsParentOfSelectionAncestor = true;
    boolean selectionAncestorIsParentOfEventTarget = true;

    Node eventTargetNode = Node.as(event.getNativeEvent().getEventTarget());
    final Range browserRange = selection.getRange();
    if (browserRange != null) {
      rangeSelectionCommonAncestor = browserRange.getCommonAncestor();
      eventTargetIsParentOfSelectionAncestor =
          eventTargetNode.isOrHasChild(rangeSelectionCommonAncestor);
      selectionAncestorIsParentOfEventTarget =
          rangeSelectionCommonAncestor.isOrHasChild(eventTargetNode);

      // Si intersection DOM entre la sélection et la cellule => stop
      if (eventTargetIsParentOfSelectionAncestor || selectionAncestorIsParentOfEventTarget) {
        return true;
      }
    }

    return false;
  }

}
